﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Yoozoo.Framework.Core;
using System.Text;
using System.Security.Cryptography;

public class ReddotManager : SingletonMono<ReddotManager>
{
    /// <summary>
    /// 根节点
    /// </summary>
    //public ReddotNode m_rootNode = new ReddotNode();
    /// <summary>
    /// 节点全局缓存表
    /// </summary>
    public Dictionary<string, ReddotNode> m_nodeDict = new Dictionary<string, ReddotNode>();
    //public Dictionary<string, ReddotNode> m_leafNodeDict = new Dictionary<string, ReddotNode>();
    //public List<ReddotNode> m_dirtyList = new List<ReddotNode>();

    /// <summary>
    /// 将节点添加到全局缓存中
    /// </summary>
    /// <param name="node"></param>
    public void SetNodeDict(ReddotNode node)
    {
        m_nodeDict[node.m_path] = node;
    }
    /// <summary>
    /// 将节点从全局缓存中删除
    /// </summary>
    /// <param name="node"></param>
    public void ClearNodeDict(ReddotNode node)
    {
        m_nodeDict.Remove(node.m_path);
    }

    public ReddotNode AddNode(string path, Func<int> func = null)
    {
        string[] paths = path.Split('.');
        /*
        ReddotNode node = m_rootNode;
        foreach (var relativePath in paths)
        {
            node = node.AddNode(relativePath);
            node.m_manager = this;
            this.SetNodeDict(node);
        }*/

        int len = paths.Length;
        if (len == 0)
        {
            UnityEngine.Debug.LogError($"[红点系统] AddNode 路径为空 path={path}");
            return null;
        }

        //取根节点
        ReddotNode node = GetNode(paths[0]);
        //根节点不存在则创建根节点
        if (node == null)
        {
            node = new ReddotNode(paths[0],paths[0]);
            node.m_manager = this;
            SetNodeDict(node);
        }
        //添加路径节点
        for (int i = 1; i < len; ++i)
        {
            node = node.AddNode(paths[i]);
            node.m_manager = this;
            this.SetNodeDict(node); 
        }
        
        //在叶子节点上添加事件调用 用以获取红点值
        node.AddListener(func);
        //m_leafNodeDict.Add(path, node);
        
        return node;
    }
    public void RemoveNode(string path)
    {
        ReddotNode node = GetNode(path);
        if (node == null)
        {
            return;
        }
        
        node.RemoveFromParent();
    }
    public ReddotNode GetNode(string path)
    {
        ReddotNode node = null;
        if (m_nodeDict.TryGetValue(path, out node))
        {
            return node;
        }

        return null;
    }

    /// <summary>
    /// 节点更新事件派送
    /// 注意 如果派送的是叶子节点 则冒泡调用
    /// 注意 如果派送的不是叶子节点的值 则递归到其所有的叶子节点 更新全部叶子节点
    /// </summary>
    public void Dispatch(string path)
    {
        ReddotNode node = GetNode(path);
        node?.Dispatch();
    }
    
    public void ResetAll()
    {
        foreach (KeyValuePair<string, ReddotNode> node in m_nodeDict.ToList())
            node.Value.Dispose();
        m_nodeDict.Clear();
    }

    static MD5 md5 = null;
    static MD5 MD5
    {
        get
        {
            if (null == md5)
                md5 = MD5.Create();
            return md5;
        }
    }
    static string ComputeHash(string content)
    {
        byte[] buffer = Encoding.UTF8.GetBytes(content);
        
        if (buffer.Length < 1)
            return "";

        byte[] hash = MD5.ComputeHash(buffer);
        StringBuilder sb = new StringBuilder();

        foreach (var b in hash)
            sb.Append(b.ToString("x2"));

        return sb.ToString();
    }
    
    
}
